2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #ifndef __JUCER_LABELHANDLER_JUCEHEADER__
27 #define __JUCER_LABELHANDLER_JUCEHEADER__
29 #include "../../properties/jucer_JustificationProperty.h"
30 #include "../../properties/jucer_FontPropertyComponent.h"
31 #include "../../properties/jucer_ComponentBooleanProperty.h"
34 //==============================================================================
37 class LabelHandler
: public ComponentTypeHandler
40 //==============================================================================
42 : ComponentTypeHandler ("Label", "Label", typeid (Label
), 150, 24)
44 registerColour (Label::backgroundColourId
, "background", "bkgCol");
45 registerColour (Label::textColourId
, "text", "textCol");
46 registerColour (Label::outlineColourId
, "outline", "outlineCol");
47 registerColour (TextEditor::textColourId
, "editor text", "edTextCol");
48 registerColour (TextEditor::backgroundColourId
, "editor bkg", "edBkgCol");
49 registerColour (TextEditor::highlightColourId
, "highlight", "hiliteCol");
52 //==============================================================================
53 Component
* createNewComponent (JucerDocument
*)
55 return new Label ("new label", "label text");
58 XmlElement
* createXmlFor (Component
* comp
, const ComponentLayout
* layout
)
60 Label
* const l
= dynamic_cast <Label
*> (comp
);
62 XmlElement
* e
= ComponentTypeHandler::createXmlFor (comp
, layout
);
63 e
->setAttribute ("labelText", l
->getText());
65 e
->setAttribute ("editableSingleClick", l
->isEditableOnSingleClick());
66 e
->setAttribute ("editableDoubleClick", l
->isEditableOnDoubleClick());
67 e
->setAttribute ("focusDiscardsChanges", l
->doesLossOfFocusDiscardChanges());
69 e
->setAttribute ("fontname", l
->getProperties().getWithDefault ("typefaceName", FontPropertyComponent::defaultFont
).toString());
70 e
->setAttribute ("fontsize", roundToInt (l
->getFont().getHeight() * 100.0) / 100.0);
71 e
->setAttribute ("bold", l
->getFont().isBold());
72 e
->setAttribute ("italic", l
->getFont().isItalic());
73 e
->setAttribute ("justification", l
->getJustificationType().getFlags());
78 bool restoreFromXml (const XmlElement
& xml
, Component
* comp
, const ComponentLayout
* layout
)
80 Label
* const l
= dynamic_cast <Label
*> (comp
);
82 if (! ComponentTypeHandler::restoreFromXml (xml
, comp
, layout
))
85 Label
defaultLabel (String::empty
, String::empty
);
88 font
.setHeight ((float) xml
.getDoubleAttribute ("fontsize", 15.0));
89 font
.setBold (xml
.getBoolAttribute ("bold", false));
90 font
.setItalic (xml
.getBoolAttribute ("italic", false));
93 l
->getProperties().set ("typefaceName", xml
.getStringAttribute ("fontname", FontPropertyComponent::defaultFont
));
96 l
->setJustificationType (Justification (xml
.getIntAttribute ("justification", Justification::centred
)));
98 l
->setText (xml
.getStringAttribute ("labelText", "Label Text"), false);
100 l
->setEditable (xml
.getBoolAttribute ("editableSingleClick", defaultLabel
.isEditableOnSingleClick()),
101 xml
.getBoolAttribute ("editableDoubleClick", defaultLabel
.isEditableOnDoubleClick()),
102 xml
.getBoolAttribute ("focusDiscardsChanges", defaultLabel
.doesLossOfFocusDiscardChanges()));
107 static void updateLabelFont (Label
* label
)
109 Font
f (label
->getFont());
110 f
= FontPropertyComponent::applyNameToFont (label
->getProperties().getWithDefault ("typefaceName", FontPropertyComponent::defaultFont
), f
);
114 const String
getCreationParameters (Component
* component
)
116 Label
* const l
= dynamic_cast <Label
*> (component
);
118 return quotedString (component
->getName())
120 + quotedString (l
->getText());
123 void fillInCreationCode (GeneratedCode
& code
, Component
* component
, const String
& memberVariableName
)
125 ComponentTypeHandler::fillInCreationCode (code
, component
, memberVariableName
);
127 Label
* const l
= dynamic_cast <Label
*> (component
);
131 s
<< memberVariableName
<< "->setFont ("
132 << FontPropertyComponent::getCompleteFontCode (l
->getFont(), l
->getProperties().getWithDefault ("typefaceName", FontPropertyComponent::defaultFont
))
134 << memberVariableName
<< "->setJustificationType ("
135 << justificationToCode (l
->getJustificationType())
137 << memberVariableName
<< "->setEditable ("
138 << boolToString (l
->isEditableOnSingleClick()) << ", "
139 << boolToString (l
->isEditableOnDoubleClick()) << ", "
140 << boolToString (l
->doesLossOfFocusDiscardChanges()) << ");\n"
141 << getColourIntialisationCode (component
, memberVariableName
);
143 if (needsCallback (component
))
144 s
<< memberVariableName
<< "->addListener (this);\n";
148 code
.constructorCode
+= s
;
151 void fillInGeneratedCode (Component
* component
, GeneratedCode
& code
)
153 ComponentTypeHandler::fillInGeneratedCode (component
, code
);
155 if (needsCallback (component
))
157 String
& callback
= code
.getCallbackCode ("public LabelListener",
159 "labelTextChanged (Label* labelThatHasChanged)",
162 if (callback
.trim().isNotEmpty())
165 const String
memberVariableName (code
.document
->getComponentLayout()->getComponentMemberVariableName (component
));
166 const String
userCodeComment ("UserLabelCode_" + memberVariableName
);
169 << "if (labelThatHasChanged == " << memberVariableName
170 << ")\n{\n //[" << userCodeComment
<< "] -- add your label text handling code here..\n //[/" << userCodeComment
<< "]\n}\n";
174 void getEditableProperties (Component
* component
, JucerDocument
& document
, Array
<PropertyComponent
*>& properties
)
176 ComponentTypeHandler::getEditableProperties (component
, document
, properties
);
178 Label
* const l
= dynamic_cast <Label
*> (component
);
179 properties
.add (new LabelTextProperty (l
, document
));
181 properties
.add (new LabelJustificationProperty (l
, document
));
182 properties
.add (new FontNameProperty (l
, document
));
183 properties
.add (new FontSizeProperty (l
, document
));
184 properties
.add (new FontStyleProperty (l
, document
));
186 addColourProperties (component
, document
, properties
);
188 properties
.add (new LabelEditableProperty (l
, document
));
190 if (l
->isEditableOnDoubleClick() || l
->isEditableOnSingleClick())
191 properties
.add (new LabelLossOfFocusProperty (l
, document
));
194 static bool needsCallback (Component
* label
)
196 return ((Label
*) label
)->isEditableOnSingleClick()
197 || ((Label
*) label
)->isEditableOnDoubleClick(); // xxx should be configurable
202 //==============================================================================
203 class LabelTextProperty
: public ComponentTextProperty
<Label
>
206 LabelTextProperty (Label
* component_
, JucerDocument
& document_
)
207 : ComponentTextProperty
<Label
> ("text", 10000, true, component_
, document_
)
210 void setText (const String
& newText
)
212 document
.perform (new LabelTextChangeAction (component
, *document
.getComponentLayout(), newText
),
213 "Change Label text");
216 const String
getText() const
218 return component
->getText();
222 class LabelTextChangeAction
: public ComponentUndoableAction
<Label
>
225 LabelTextChangeAction (Label
* const comp
, ComponentLayout
& layout
, const String
& newState_
)
226 : ComponentUndoableAction
<Label
> (comp
, layout
),
229 oldState
= comp
->getText();
235 getComponent()->setText (newState
, false);
243 getComponent()->setText (oldState
, false);
248 String newState
, oldState
;
252 //==============================================================================
253 class LabelEditableProperty
: public ComponentChoiceProperty
<Label
>
256 LabelEditableProperty (Label
* component_
,
257 JucerDocument
& document_
)
258 : ComponentChoiceProperty
<Label
> ("editing", component_
, document_
)
260 choices
.add ("read-only");
261 choices
.add ("edit on single-click");
262 choices
.add ("edit on double-click");
265 void setIndex (int newIndex
)
267 document
.perform (new LabelEditableChangeAction (component
, *document
.getComponentLayout(), newIndex
),
268 "Change Label editability");
273 return component
->isEditableOnSingleClick()
275 : (component
->isEditableOnDoubleClick() ? 2 : 0);
279 class LabelEditableChangeAction
: public ComponentUndoableAction
<Label
>
282 LabelEditableChangeAction (Label
* const comp
, ComponentLayout
& layout
, const int newState_
)
283 : ComponentUndoableAction
<Label
> (comp
, layout
),
286 oldState
= comp
->isEditableOnSingleClick()
288 : (comp
->isEditableOnDoubleClick() ? 2 : 0);
294 getComponent()->setEditable (newState
== 1, newState
>= 1, getComponent()->doesLossOfFocusDiscardChanges());
296 layout
.getSelectedSet().changed();
303 getComponent()->setEditable (oldState
== 1, oldState
>= 1, getComponent()->doesLossOfFocusDiscardChanges());
305 layout
.getSelectedSet().changed();
309 int newState
, oldState
;
313 //==============================================================================
314 class LabelLossOfFocusProperty
: public ComponentChoiceProperty
<Label
>
317 LabelLossOfFocusProperty (Label
* component_
,
318 JucerDocument
& document_
)
319 : ComponentChoiceProperty
<Label
> ("focus", component_
, document_
)
321 choices
.add ("loss of focus discards changes");
322 choices
.add ("loss of focus commits changes");
325 void setIndex (int newIndex
)
327 document
.perform (new LabelFocusLossChangeAction (component
, *document
.getComponentLayout(), newIndex
== 0),
328 "Change Label focus behaviour");
333 return component
->doesLossOfFocusDiscardChanges() ? 0 : 1;
337 class LabelFocusLossChangeAction
: public ComponentUndoableAction
<Label
>
340 LabelFocusLossChangeAction (Label
* const comp
, ComponentLayout
& layout
, const bool newState_
)
341 : ComponentUndoableAction
<Label
> (comp
, layout
),
344 oldState
= comp
->doesLossOfFocusDiscardChanges();
350 getComponent()->setEditable (getComponent()->isEditableOnSingleClick(),
351 getComponent()->isEditableOnDoubleClick(),
360 getComponent()->setEditable (getComponent()->isEditableOnSingleClick(),
361 getComponent()->isEditableOnDoubleClick(),
367 bool newState
, oldState
;
371 //==============================================================================
372 class LabelJustificationProperty
: public JustificationProperty
,
373 public ChangeListener
376 LabelJustificationProperty (Label
* const label_
, JucerDocument
& document_
)
377 : JustificationProperty ("layout", false),
381 document
.addChangeListener (this);
384 ~LabelJustificationProperty()
386 document
.removeChangeListener (this);
389 void setJustification (const Justification
& newJustification
)
391 document
.perform (new LabelJustifyChangeAction (label
, *document
.getComponentLayout(), newJustification
),
392 "Change Label justification");
395 const Justification
getJustification() const
397 return label
->getJustificationType();
400 void changeListenerCallback (ChangeBroadcaster
*) { refresh(); }
404 JucerDocument
& document
;
406 class LabelJustifyChangeAction
: public ComponentUndoableAction
<Label
>
409 LabelJustifyChangeAction (Label
* const comp
, ComponentLayout
& layout
, const Justification
& newState_
)
410 : ComponentUndoableAction
<Label
> (comp
, layout
),
411 newState (newState_
),
412 oldState (comp
->getJustificationType())
419 getComponent()->setJustificationType (newState
);
427 getComponent()->setJustificationType (oldState
);
432 Justification newState
, oldState
;
436 //==============================================================================
437 class FontNameProperty
: public FontPropertyComponent
,
438 public ChangeListener
441 FontNameProperty (Label
* const label_
,
442 JucerDocument
& document_
)
443 : FontPropertyComponent ("font"),
447 document
.addChangeListener (this);
452 document
.removeChangeListener (this);
455 void setTypefaceName (const String
& newFontName
)
457 document
.perform (new FontNameChangeAction (label
, *document
.getComponentLayout(), newFontName
),
458 "Change Label typeface");
461 const String
getTypefaceName() const
463 return label
->getProperties().getWithDefault ("typefaceName", FontPropertyComponent::defaultFont
);
466 void changeListenerCallback (ChangeBroadcaster
*) { refresh(); }
470 JucerDocument
& document
;
472 class FontNameChangeAction
: public ComponentUndoableAction
<Label
>
475 FontNameChangeAction (Label
* const comp
, ComponentLayout
& layout
, const String
& newState_
)
476 : ComponentUndoableAction
<Label
> (comp
, layout
),
479 oldState
= comp
->getProperties().getWithDefault ("typefaceName", FontPropertyComponent::defaultFont
);
485 getComponent()->getProperties().set ("typefaceName", newState
);
486 LabelHandler::updateLabelFont (getComponent());
494 getComponent()->getProperties().set ("typefaceName", oldState
);
495 LabelHandler::updateLabelFont (getComponent());
500 String newState
, oldState
;
504 //==============================================================================
505 class FontSizeProperty
: public SliderPropertyComponent
,
506 public ChangeListener
509 FontSizeProperty (Label
* const label_
, JucerDocument
& document_
)
510 : SliderPropertyComponent ("size", 1.0, 250.0, 0.1, 0.3),
514 document
.addChangeListener (this);
519 document
.removeChangeListener (this);
522 void setValue (double newValue
)
524 document
.getUndoManager().undoCurrentTransactionOnly();
526 document
.perform (new FontSizeChangeAction (label
, *document
.getComponentLayout(), (float) newValue
),
527 "Change Label font size");
530 double getValue() const
532 return label
->getFont().getHeight();
535 void changeListenerCallback (ChangeBroadcaster
*) { refresh(); }
539 JucerDocument
& document
;
541 class FontSizeChangeAction
: public ComponentUndoableAction
<Label
>
544 FontSizeChangeAction (Label
* const comp
, ComponentLayout
& layout
, const float newState_
)
545 : ComponentUndoableAction
<Label
> (comp
, layout
),
548 oldState
= comp
->getFont().getHeight();
554 Font
f (getComponent()->getFont());
555 f
.setHeight ((float) newState
);
556 getComponent()->setFont (f
);
564 Font
f (getComponent()->getFont());
565 f
.setHeight ((float) oldState
);
566 getComponent()->setFont (f
);
571 float newState
, oldState
;
575 //==============================================================================
576 class FontStyleProperty
: public ChoicePropertyComponent
,
577 public ChangeListener
580 FontStyleProperty (Label
* const label_
, JucerDocument
& document_
)
581 : ChoicePropertyComponent ("style"),
585 document
.addChangeListener (this);
587 choices
.add ("normal");
588 choices
.add ("bold");
589 choices
.add ("italic");
590 choices
.add ("bold + italic");
595 document
.removeChangeListener (this);
598 void setIndex (int newIndex
)
600 Font
f (label
->getFont());
602 f
.setBold (newIndex
== 1 || newIndex
== 3);
603 f
.setItalic (newIndex
== 2 || newIndex
== 3);
605 document
.perform (new FontStyleChangeAction (label
, *document
.getComponentLayout(), f
),
606 "Change Label font style");
611 if (label
->getFont().isBold() && label
->getFont().isItalic())
613 else if (label
->getFont().isBold())
615 else if (label
->getFont().isItalic())
621 void changeListenerCallback (ChangeBroadcaster
*) { refresh(); }
625 JucerDocument
& document
;
627 class FontStyleChangeAction
: public ComponentUndoableAction
<Label
>
630 FontStyleChangeAction (Label
* const comp
, ComponentLayout
& layout
, const Font
& newState_
)
631 : ComponentUndoableAction
<Label
> (comp
, layout
),
634 oldState
= comp
->getFont();
640 getComponent()->setFont (newState
);
648 getComponent()->setFont (oldState
);
653 Font newState
, oldState
;
659 #endif // __JUCER_LABELHANDLER_JUCEHEADER__